#ifndef CIRCULARBUFFERDB_H
#define CIRCULARBUFFERDB_H

#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <mutex>
#include <atomic>
#include <sqlite3.h>
#include <type_traits> // for std::is_same and std::is_pod
#include <chrono>
#include <ctime>
#include <algorithm> // 包含 std::reverse
#include <functional> // 包含 std::function

template <typename T>
class CircularBufferDB
{
public:
    // 初始化数据库
    CircularBufferDB(const std::string &filename, size_t max_records = 1000)
        : filename_(filename), max_records_(max_records)
    {
        static_assert(std::is_pod<T>::value, "Record type must be POD");

        // 打开或创建数据库
        int rc = sqlite3_open(filename_.c_str(), &db_);
        if (rc != SQLITE_OK)
        {
            throw std::runtime_error("Failed to open database");
        }

        // 创建表
        const char *sql = "CREATE TABLE IF NOT EXISTS records ("
                          "id INTEGER PRIMARY KEY AUTOINCREMENT, "
                          "timestamp INTEGER, "
                          "data BLOB);";
        char *zErrMsg = nullptr;
        rc = sqlite3_exec(db_, sql, nullptr, nullptr, &zErrMsg);
        if (rc != SQLITE_OK)
        {
            sqlite3_free(zErrMsg);
            throw std::runtime_error("Failed to create table");
        }
    }

    ~CircularBufferDB()
    {
        sqlite3_close(db_);
    }

    // 添加记录（线程安全）
    void AddRecord(const T &record)
    {
        std::lock_guard<std::mutex> lock(mutex_);

        // 获取当前时间戳（如果记录包含时间戳字段）
        if (std::is_same<decltype(T::timestamp), time_t>::value)
        {
            const_cast<T &>(record).timestamp = time(nullptr);
        }

        // 插入记录
        const char *sql = "INSERT INTO records (timestamp, data) VALUES (?, ?);";
        sqlite3_stmt *stmt;
        int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
        if (rc != SQLITE_OK)
        {
            throw std::runtime_error("Failed to prepare statement");
        }

        sqlite3_bind_int64(stmt, 1, record.timestamp);
        sqlite3_bind_blob(stmt, 2, &record, sizeof(T), SQLITE_STATIC);

        rc = sqlite3_step(stmt);
        if (rc != SQLITE_DONE)
        {
            sqlite3_finalize(stmt);
            throw std::runtime_error("Failed to insert record");
        }

        sqlite3_finalize(stmt);

        // 删除多余的记录
        size_t current_count = GetRecordCount();
        if (current_count > max_records_)
        {
            size_t to_delete = current_count - max_records_;
            const char *delete_sql = "DELETE FROM records ORDER BY id ASC LIMIT ?;";
            sqlite3_stmt *delete_stmt;
            rc = sqlite3_prepare_v2(db_, delete_sql, -1, &delete_stmt, nullptr);
            if (rc != SQLITE_OK)
            {
                throw std::runtime_error("Failed to prepare delete statement");
            }

            sqlite3_bind_int(delete_stmt, 1, to_delete);

            rc = sqlite3_step(delete_stmt);
            if (rc != SQLITE_DONE)
            {
                sqlite3_finalize(delete_stmt);
                throw std::runtime_error("Failed to delete records");
            }

            sqlite3_finalize(delete_stmt);
        }
    }

    // 读取记录（线程安全）
    std::vector<T> ReadRecords(size_t max_count = 0) const
    {
        std::lock_guard<std::mutex> lock(mutex_);

        const char *sql = "SELECT data FROM records ORDER BY id DESC LIMIT ?;";
        sqlite3_stmt *stmt;
        int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
        if (rc != SQLITE_OK)
        {
            throw std::runtime_error("Failed to prepare statement");
        }

        if (max_count == 0)
        {
            max_count = max_records_;
        }
        sqlite3_bind_int(stmt, 1, max_count);

        std::vector<T> result;
        while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
        {
            const void *data = sqlite3_column_blob(stmt, 0);
            result.emplace_back(*static_cast<const T *>(data));
        }

        if (rc != SQLITE_DONE)
        {
            sqlite3_finalize(stmt);
            throw std::runtime_error("Failed to read records");
        }

        sqlite3_finalize(stmt);

        // 反转结果以按时间顺序排列
        std::reverse(result.begin(), result.end());

        return result;
    }

    // 配置相关方法
    void Resize(size_t new_max_records)
    {
        std::lock_guard<std::mutex> lock(mutex_);

        max_records_ = new_max_records;

        // 删除多余的记录
        size_t current_count = GetRecordCount();
        if (current_count > max_records_)
        {
            size_t to_delete = current_count - max_records_;
            const char *delete_sql = "DELETE FROM records ORDER BY id ASC LIMIT ?;";
            sqlite3_stmt *delete_stmt;
            int rc = sqlite3_prepare_v2(db_, delete_sql, -1, &delete_stmt, nullptr);
            if (rc != SQLITE_OK)
            {
                throw std::runtime_error("Failed to prepare delete statement");
            }

            sqlite3_bind_int(delete_stmt, 1, to_delete);

            rc = sqlite3_step(delete_stmt);
            if (rc != SQLITE_DONE)
            {
                sqlite3_finalize(delete_stmt);
                throw std::runtime_error("Failed to delete records");
            }

            sqlite3_finalize(delete_stmt);
        }
    }

    // 导出数据库到文本文件（线程安全）
    void ExportToTextFile(const std::string &filename, std::function<std::string(const T&)> recordToString) const
    {
        std::lock_guard<std::mutex> lock(mutex_);

        // 打开文件
        std::ofstream file(filename);
        if (!file.is_open())
        {
            throw std::runtime_error("Failed to open file for writing");
        }

        const char *sql = "SELECT timestamp, data FROM records ORDER BY id DESC;";
        sqlite3_stmt *stmt;
        int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
        if (rc != SQLITE_OK)
        {
            throw std::runtime_error("Failed to prepare statement");
        }

        while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
        {
            time_t timestamp = sqlite3_column_int64(stmt, 0);
            const void *data = sqlite3_column_blob(stmt, 1);
            size_t data_size = sqlite3_column_bytes(stmt, 1);

            // 将时间戳转换为可读格式
            std::tm tm_struct = *std::localtime(&timestamp);
            char time_str[100];
            std::strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &tm_struct);

            // 将数据转换为字符串
            T record = *static_cast<const T *>(data);
            std::string data_str = recordToString(record);

            // 写入文件
            file << "Timestamp: " << time_str << "\t";
            file << "Data: " << data_str << "\n";
        }

        if (rc != SQLITE_DONE)
        {
            sqlite3_finalize(stmt);
            throw std::runtime_error("Failed to read records");
        }

        sqlite3_finalize(stmt);
        file.close();
    }

    // 时间范围查询（线程安全）
    std::vector<T> GetRecordsByTime(
        const std::chrono::system_clock::time_point& start,
        const std::chrono::system_clock::time_point& end) 
    {
        std::lock_guard<std::mutex> lock(mutex_);

        // 将时间点转换为 time_t 类型
        time_t start_time = std::chrono::system_clock::to_time_t(start);
        time_t end_time = std::chrono::system_clock::to_time_t(end);

        const char *sql = "SELECT data FROM records WHERE timestamp BETWEEN ? AND ? ORDER BY id DESC;";
        sqlite3_stmt *stmt;
        int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
        if (rc != SQLITE_OK)
        {
            throw std::runtime_error("Failed to prepare statement");
        }

        sqlite3_bind_int64(stmt, 1, start_time);
        sqlite3_bind_int64(stmt, 2, end_time);

        std::vector<T> result;
        while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
        {
            const void *data = sqlite3_column_blob(stmt, 0);
            result.emplace_back(*static_cast<const T *>(data));
        }

        if (rc != SQLITE_DONE)
        {
            sqlite3_finalize(stmt);
            throw std::runtime_error("Failed to read records");
        }

        sqlite3_finalize(stmt);

        // 反转结果以按时间顺序排列
        std::reverse(result.begin(), result.end());

        return result;
    }
    // 获取数据库大小
    size_t GetSize() const
    {
        return GetRecordCount();
    }

private:
    sqlite3 *db_ = nullptr; // SQLite 数据库连接
    std::string filename_;     // 文件名
    size_t max_records_;       // 最大记录数
    mutable std::mutex mutex_; // 普通互斥锁

    // 获取记录总数
    size_t GetRecordCount() const
    {
        const char *sql = "SELECT COUNT(*) FROM records;";
        sqlite3_stmt *stmt;
        int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
        if (rc != SQLITE_OK)
        {
            throw std::runtime_error("Failed to prepare statement");
        }

        rc = sqlite3_step(stmt);
        if (rc != SQLITE_ROW)
        {
            sqlite3_finalize(stmt);
            throw std::runtime_error("Failed to get record count");
        }

        size_t count = sqlite3_column_int(stmt, 0);
        sqlite3_finalize(stmt);

        return count;
    }

    // 清空数据库（线程安全） 没测试
    void Clear() 
    {
        std::lock_guard<std::mutex> lock(mutex_);
        const char *sql = "DELETE FROM records;";
        char *zErrMsg = nullptr;
        int rc = sqlite3_exec(db_, sql, nullptr, nullptr, &zErrMsg);
        if (rc!= SQLITE_OK)
        {
            sqlite3_free(zErrMsg);
            throw std::runtime_error("Failed to clear database");
        }
    }
    
};

#endif // CIRCULARBUFFERDB_H